package com.qinggeng.project.system.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qinggeng.common.enums.CommonEnum;
import com.qinggeng.common.enums.ShowTypeEnum;
import com.qinggeng.common.enums.UserTypeEnum;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.DateUtils;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.framework.config.mq.MQSendUtils;
import com.qinggeng.framework.config.mq.dto.MessageBulletChatUserAddCartDTO;
import com.qinggeng.framework.config.mq.enums.MQTypeEnum;
import com.qinggeng.project.api.dto.AddCartDTO;
import com.qinggeng.project.api.dto.CartDto;
import com.qinggeng.project.api.dto.GoodsInfoDto;
import com.qinggeng.project.api.security.utils.ApiUtils;
import com.qinggeng.project.system.domain.UserCart;
import com.qinggeng.project.system.domain.json.UserCartParams;
import com.qinggeng.project.system.domain.vo.UserCartVO;
import com.qinggeng.project.system.mapper.SysUserMapper;
import com.qinggeng.project.system.mapper.UserCartMapper;
import com.qinggeng.project.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户购物车信息Service业务层处理
 *
 * @author qinggeng
 * @date 2020-06-16
 */
@Service
@Slf4j
public class UserCartServiceImpl implements IUserCartService {
    @Resource
    private UserCartMapper userCartMapper;

    @Resource
    private IGoodsService goodsService;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private IGoodsClassifyService goodsClassifyService;

    @Resource
    private ISysConfigService sysConfigService;

    @Resource
    private SysUserMapper sysUserMapper;

    @Autowired
    private IUserGoodsLimitRecordService goodsLimitRecordService;


    private static final String USER_GOODS_CART = "USER_GOODS_CART:";

    @Autowired
    private MQSendUtils mqSendUtils;
    @Autowired
    private IUserGoodsLimitRecordService userGoodsLimitRecordService;


    /**
     * 查询用户购物车信息
     *
     * @param cartId 用户购物车信息ID
     * @return 用户购物车信息
     */
    @Override
    public UserCart selectUserCartById(Long cartId) {
        return userCartMapper.selectUserCartById(cartId);
    }

    /**
     * 查询用户购物车信息列表
     *
     * @param userCart 用户购物车信息
     * @return 用户购物车信息
     */
    @Override
    public List<UserCart> selectUserCartList(UserCart userCart) {
        return userCartMapper.selectUserCartList(userCart);
    }

    /**
     * 新增用户购物车信息
     *
     * @param userCart 用户购物车信息
     * @return 结果
     */
    @Override
    public int insertUserCart(UserCart userCart) {
        userCart.setCreateTime(DateUtils.getNowDate());
        return userCartMapper.insertUserCart(userCart);
    }

    /**
     * 修改用户购物车信息
     *
     * @param userCart 用户购物车信息
     * @return 结果
     */
    @Override
    public int updateUserCart(UserCart userCart) {
        userCart.setUpdateTime(DateUtils.getNowDate());
        return userCartMapper.updateUserCart(userCart);
    }

    /**
     * 批量删除用户购物车信息
     *
     * @param cartIds 需要删除的用户购物车信息ID
     * @return 结果
     */
    @Override
    public int deleteUserCartByIds(Long[] cartIds) {
        return userCartMapper.deleteUserCartByIds(cartIds);
    }

    /**
     * 删除用户购物车信息信息
     *
     * @param cartId 用户购物车信息ID
     * @return 结果
     */
    @Override
    public int deleteUserCartById(Long cartId) {
        return userCartMapper.deleteUserCartById(cartId);
    }

    @Override
    public UserCart selectUserCartByUserId(Long goodsId, Long shopId, Long userId) {
        return userCartMapper.selectUserCartByUserId(goodsId, shopId, userId);
    }

    @Override
    public List<CartDto> selectUserCartDtoList(UserCart userCart) {
        List<CartDto> cartDtos = userCartMapper.selectUserCartDtoList(userCart);
        for (CartDto cartDto : cartDtos) {
            cartDto.setLimitNum(userGoodsLimitRecordService.getUserGoodsLimitRemainNum(cartDto.getGoodsId()));
            if (cartDto.getGoodsType().equals("50")){
                cartDto.setStartDateStamp(cartDto.getStartDate().getTime()+"");
            }
        }
        return cartDtos;
    }

    @Override
    public CartDto selectUserCartDtoById(Long cartId) {
        return userCartMapper.selectUserCartDtoById(cartId);
    }

    @Override
    public Long selectUserCartGoodsNumByUserId(Long userId) {
        return userCartMapper.selectUserCartGoodsNumByUserId(userId);
    }

    @Override
    public Long addCart(AddCartDTO dto) {
        if (dto.getCourierId() != null){
            Long courierId = sysUserMapper.selectUserIdByPhoneNumberAndUserType(ApiUtils.getApiUser().getUser().getPhonenumber(), UserTypeEnum.COURIER.getCode());
            if (courierId!=null&&courierId.equals(dto.getCourierId())){
                dto.setCourierId(null);
            }

        }
        Long goodsId = dto.getGoodsId();
        Long shopId = dto.getShopId();
        Long courierId = dto.getCourierId();
        final Long userId = dto.getUserId();
        String key = USER_GOODS_CART +userId+":"+goodsId;
        GoodsInfoDto goodsInfoDto=null;
        Long number=0L;
        final RLock lock = redissonClient.getLock(key);
        final boolean locked = lock.isLocked();
        if (locked) {
            throw new CustomException("服务器繁忙");
        }
        lock.lock(100, TimeUnit.MILLISECONDS);
        try {
            goodsInfoDto = goodsService.selectGoodsDtoById(goodsId, shopId);
            if (goodsInfoDto == null || !goodsInfoDto.getStatus().equals(CommonEnum.STATUS_20.getValue())) {
                throw new CustomException("商品已下架！");
            }
            if (goodsInfoDto.getKeepNum() < 1) {
                throw new CustomException("已被抢光，无法添加！");
            }

            //查询购物车中是否存在该商品
            UserCart userCart = selectUserCartByUserId(goodsId, shopId, userId);
            if (userCart == null) {
                if (goodsInfoDto.getKeepNum() < dto.getGoodsNum()) {
                    throw new CustomException("已被抢光，无法添加！");
                }
                //获取限制商品的可加入购物车数量
                goodsLimitRecordService.checkIsGoodsLimit(goodsId,dto.getGoodsNum(),0);
                userCart = new UserCart();
                userCart.setUserId(ApiUtils.getUserId());
                userCart.setShopId(shopId);
                userCart.setGoodsId(goodsId);
                userCart.setGoodsKeepId(goodsInfoDto.getKeepId());
                userCart.setGoodsNum(dto.getGoodsNum());
                userCart.setCourierId(dto.getCourierId());
                insertUserCart(userCart);
            } else {

                if (goodsInfoDto.getKeepNum() < userCart.getGoodsNum() + dto.getGoodsNum()) {
                    throw new CustomException("已被抢光，无法添加！");
                }
                //获取限制商品的可加入购物车数量
                goodsLimitRecordService.checkIsGoodsLimit(goodsId,dto.getGoodsNum(),userCart.getGoodsNum());
                userCart.setGoodsNum(userCart.getGoodsNum() + dto.getGoodsNum());
                userCart.setCourierId(dto.getCourierId());
                updateUserCart(userCart);
            }
            number = selectUserCartGoodsNumByUserId(userId);
        } catch (Exception e) {
            throw new CustomException(e.getMessage());
        } finally {
            if (lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }
        String goodsName=goodsInfoDto.getGoodsName();
        MessageBulletChatUserAddCartDTO messageBulletChatUserAddCartDTO=new MessageBulletChatUserAddCartDTO();
        messageBulletChatUserAddCartDTO.setUserId(userId);
        messageBulletChatUserAddCartDTO.setGoodsName(goodsName);
        messageBulletChatUserAddCartDTO.setType(MQTypeEnum.USER_ADD_CART.getType());
        mqSendUtils.sendAsynMessage(messageBulletChatUserAddCartDTO);
        return number;
    }

    /**
     * 查询购物车预售商品
     *
     * @param userCartParams
     * @return
     */
    @Override
    public List<UserCartVO> selectUserCartDtoListForPresale(UserCartParams userCartParams) {
        return userCartMapper.selectUserCartDtoListForPresale(userCartParams);
    }

    public Map<String, String> judgeCartHaveBuyGoodsPlus(String cartIds,String totalPrice){
        Map<String, String> resultData = judgeCartHaveBuyGoods(cartIds);
        String config1 = (String) sysConfigService.selectConfigByKey("sys.send.oil");
        JSONObject params1 = JSONObject.parseObject(config1);
        if (params1 == null) {
            log.info("UserCartServiceImpl.judgeCartHaveBuyGoods()params1= {}", params1);
            throw new CustomException("系统异常");
        }
        String soloMoney = params1.getString("soloMoney");
        if (StringUtils.isEmpty(soloMoney)){
            throw new CustomException("soloMoney= "+soloMoney);
        }
        String oilMoney = new BigDecimal(totalPrice).divide(new BigDecimal(soloMoney+""),0,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(5+"")).toString();
        String sendOilOpen = params1.getString("sendOilOpen");
        String oilText = params1.getString("oilText");
        String shareContext = params1.getString("shareContext");
        String shareTitle = params1.getString("shareTitle");
        String shareImg = params1.getString("shareImg");
        String shareUrl = params1.getString("shareUrl");

        if ("0".equals(sendOilOpen)){
            resultData.put("sendOilOpen","0");
            resultData.put("oilText",oilText);
            resultData.put("oilMoney",oilMoney);
            resultData.put("shareContext",shareContext);
            resultData.put("shareTitle",shareTitle);
            resultData.put("shareImg",shareImg);
            resultData.put("shareUrl",shareUrl);
            return resultData;
        }

        if (StringUtils.isNotEmpty(oilMoney) && Double.parseDouble(oilMoney)<5){
            resultData.put("sendOilOpen","0");
            resultData.put("oilText",oilText);
            resultData.put("oilMoney",oilMoney);
            resultData.put("shareContext",shareContext);
            resultData.put("shareTitle",shareTitle);
            resultData.put("shareImg",shareImg);
            resultData.put("shareUrl",shareUrl);
            return resultData;
        }

        if ("1".equals(sendOilOpen)){
            resultData.put("sendOilOpen","1");
            oilText = oilText.replaceAll("¥", oilMoney+"元");
            resultData.put("oilText",oilText);
            resultData.put("oilMoney",oilMoney+"元");
            resultData.put("shareContext",shareContext);
            resultData.put("shareTitle",shareTitle);
            resultData.put("shareImg",shareImg);
            resultData.put("shareUrl",shareUrl);
            return resultData;
        }
        throw new CustomException("系统繁忙");
    }


    /**
     * 判断购物车是否含有活动参与商品
     *
     * @param cartIds
     * @return
     */
    @Override
    public Map<String, String> judgeCartHaveBuyGoods(String cartIds) {
        String config = (String) sysConfigService.selectConfigByKey("sys.buy.send");
        JSONObject params = JSONObject.parseObject(config);
        if (params == null) {
            log.info("UserCartServiceImpl.judgeCartHaveBuyGoods()params= {}", params);
            throw new CustomException("系统异常");
        }
        //活动未开启
        String open = params.getString("open");
        if ("0".equals(open)) {
            return dataResult("0","","");
        }

        if (StringUtils.isEmpty(cartIds)) {
            log.info("UserCartServiceImpl.judgeCartHaveBuyGoods()cartIds= {}", cartIds);
            throw new CustomException("购物车ID数组为空");
        }
        String[] cartIdsArray = cartIds.split(",");
        List<CartDto> cartDtoList = Lists.newArrayList();

        for (String cartId : cartIdsArray) {
            CartDto cartDto = userCartMapper.selectUserCartDtoById(Long.parseLong(cartId));
            if (cartDto == null) {
                log.info("UserCartServiceImpl.judgeCartHaveBuyGoods()cartDto= {}", cartDto);
                throw new CustomException("购物车ID不存在");
            }
            cartDtoList.add(cartDto);
        }


        if (cartDtoList.size() <= 0) {
            throw new CustomException("请选择商品", ShowTypeEnum.用户.getValue());
        }


        String buyClassifyName = params.getString("buyClassifyName");
        String sendClassifyName = params.getString("sendClassifyName");
        String money = params.getString("money");

        if (StringUtils.isEmpty(money)){
            log.info("judgeCartHaveBuyGoods.judgeCartHaveBuyGoods(),money= {}",money);
            throw new CustomException("money is null");
        }

        //弹出文本信息
        String text = params.getString("text");
        String freeText = params.getString("freeText");
        String amount = params.getString("amount");
        //获取父分类名称等于此条件的子分类集合
        //要买的种类
        if (StringUtils.isEmpty(buyClassifyName)){
            log.info("judgeCartHaveBuyGoods.judgeCartHaveBuyGoods(),buyClassifyName= {}",buyClassifyName);
            throw new CustomException("buyClassifyName is null");
        }
        List<Long> buyClassifyIds = goodsClassifyService.selectGoodsClassifyIdsByCondition(buyClassifyName);

        //要送的种类
        if (StringUtils.isEmpty(sendClassifyName)){
            log.info("judgeCartHaveBuyGoods.judgeCartHaveBuyGoods(),sendClassifyName= {}",sendClassifyName);
            throw new CustomException("sendClassifyName is null");
        }
        List<Long> sendClassifyIds = goodsClassifyService.selectGoodsClassifyIdsByCondition(sendClassifyName);

        //过滤出购物车中不含买的品种的对象
        List<CartDto> collectNotBuy = cartDtoList.stream().filter(a -> {
            return buyClassifyIds.stream().filter(b -> {
                return b.equals(a.getClassifyId());
            }).count() <= 0;
        }).collect(Collectors.toList());
        //集合元素个数不相等说明含有需要买的对象
        if (collectNotBuy.size() > 0 && collectNotBuy.size() != cartDtoList.size()) {
            //过滤出含有送出的对象
            List<CartDto> collectHaveSend = collectNotBuy.stream().filter(a -> {
                return sendClassifyIds.stream().filter(b -> {
                    return b.equals(a.getClassifyId());
                }).count() >= 1;
            }).collect(Collectors.toList());
            if (collectHaveSend.size()>0){
                if (money.equals("0")){
                    freeText = freeText.replaceAll("#",amount);
                    return dataResult("1",money,freeText);
                }
                text = text.replaceAll("¥", money);
                text = text.replaceAll("#",amount);
                return dataResult("1",money,text);
            }
        }

        return dataResult("0",money,"");
    }

    public Map<String,String> dataResult(String open,String money,String text){
        Map<String,String> data = new HashMap<>();
        data.put("open",open);
        data.put("money",money);
        data.put("text",text);
        return data;
    }


    /**
     * 根据购物车ids,查询购物车商品集合
     * @param cartIdsArray
     * @return
     */
    @Override
    public List<CartDto> selectUserCartDtoByIds(String[] cartIdsArray) {
        return userCartMapper.selectUserCartDtoByIds(cartIdsArray);
    }
}
